package com.logistics.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.logistics.common.Constants;
import com.logistics.dto.LoginRequest;
import com.logistics.entity.PlatformTenant;
import com.logistics.entity.SysUser;
import com.logistics.mapper.PlatformTenantMapper;
import com.logistics.mapper.SysUserMapper;
import com.logistics.security.JwtTokenProvider;
import com.logistics.vo.LoginResponse;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * 认证服务
 */
@Service
public class AuthService {
    
    private final SysUserMapper userMapper;
    private final PlatformTenantMapper tenantMapper;
    private final PasswordEncoder passwordEncoder;
    private final JwtTokenProvider jwtTokenProvider;
    private final PermissionService permissionService;
    
    public AuthService(SysUserMapper userMapper,
                      PlatformTenantMapper tenantMapper,
                      PasswordEncoder passwordEncoder,
                      JwtTokenProvider jwtTokenProvider,
                      PermissionService permissionService) {
        this.userMapper = userMapper;
        this.tenantMapper = tenantMapper;
        this.passwordEncoder = passwordEncoder;
        this.jwtTokenProvider = jwtTokenProvider;
        this.permissionService = permissionService;
    }
    
    /**
     * 用户登录
     */
    public LoginResponse login(LoginRequest request) {
        // 1. 确定租户ID
        Long tenantId = determineTenantId(request);
        
        // 2. 查询用户
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getTenantId, tenantId)
                   .eq(SysUser::getUsername, request.getUsername())
                   .eq(SysUser::getStatus, 1);
        
        SysUser user = userMapper.selectOne(queryWrapper);
        
        if (user == null) {
            throw new RuntimeException("用户名或密码错误");
        }
        
        // 3. 验证密码
        if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
            throw new RuntimeException("用户名或密码错误");
        }
        
        // 4. 如果是租户用户，检查租户状态
        if (tenantId > 0) {
            PlatformTenant tenant = tenantMapper.selectById(tenantId);
            if (tenant == null || tenant.getStatus() == 0) {
                throw new RuntimeException("租户已停用，请联系管理员");
            }
            if ("EXPIRED".equals(tenant.getSubscriptionStatus())) {
                throw new RuntimeException("订阅已过期，请续费");
            }
        }
        
        // 5. 获取用户权限
        List<String> permissions = permissionService.getUserPermissionCodes(user.getId());
        
        // 5.1 获取用户角色信息（新增：用于权限计算）
        List<LoginResponse.RoleInfo> roles = permissionService.getUserRoleInfos(user.getId());
        
        // 5.2 获取用户自定义权限码（可编辑角色的权限）
        List<String> authorityCodes = permissionService.getUserAuthorityCodes(user.getId());
        
        // 5.3 获取已开通的模块资源编码（暂时返回全部，后续根据订阅套餐动态获取）
        List<String> moduleResourceCodes = java.util.Arrays.asList("ALL");
        
        // 6. 生成 Token（包含权限点）
        String token = jwtTokenProvider.generateToken(
            user.getId(),
            user.getTenantId(),
            user.getSiteId(),
            user.getUsername(),
            user.getRole(),
            permissions
        );
        
        // 7. 构造用户信息
        LoginResponse.UserInfo userInfo = new LoginResponse.UserInfo(
            user.getId(),
            user.getTenantId(),
            user.getSiteId(),  // 添加站点ID
            user.getUsername(),
            user.getRealName(),
            user.getPhone(),
            user.getRole(),
            user.getStatus(),
            permissions,  // 旧版兼容
            roles,  // 新增：角色列表
            authorityCodes,  // 新增：自定义权限码
            moduleResourceCodes  // 新增：模块资源编码
        );
        
        // 8. 更新最后登录时间（TODO: 可以异步处理）
        // user.setLastLoginTime(LocalDateTime.now());
        // userMapper.updateById(user);
        
        return new LoginResponse(token, userInfo);
    }
    
    /**
     * 确定租户ID
     */
    private Long determineTenantId(LoginRequest request) {
        // 如果有租户编码，说明是租户端登录
        if (StringUtils.hasText(request.getTenantCode())) {
            LambdaQueryWrapper<PlatformTenant> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PlatformTenant::getTenantCode, request.getTenantCode());
            PlatformTenant tenant = tenantMapper.selectOne(wrapper);
            
            if (tenant == null) {
                throw new RuntimeException("租户不存在");
            }
            
            return tenant.getId();
        }
        
        // 否则是平台管理员登录
        return Constants.PLATFORM_TENANT_ID;
    }
}

